package easier.camera;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.PointF;
import android.graphics.Rect;
import android.media.Image;
import android.os.Bundle;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ExperimentalGetImage;
import androidx.camera.core.ImageAnalysis.Analyzer;
import androidx.camera.core.ImageProxy;
import androidx.camera.core.UseCase;
import androidx.camera.view.PreviewView;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.mlkit.vision.common.InputImage;
import com.google.mlkit.vision.face.Face;
import com.google.mlkit.vision.face.FaceContour;
import com.google.mlkit.vision.face.FaceDetection;
import com.google.mlkit.vision.face.FaceDetector;
import com.google.mlkit.vision.face.FaceDetectorOptions;
import com.google.mlkit.vision.face.FaceLandmark;
import easier.camera.x.CameraXManager;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class MainActivity4 extends AppCompatActivity {

    private static final String TAG = "MainActivity4";

    private PreviewView mPreviewView;
    private ImageView mImage;
    private CameraXManager mXManager;
    private FaceDetector mDetector;


    public static void start( Context context ) {

        Intent starter = new Intent( context, MainActivity4.class );
        context.startActivity( starter );
    }

    @Override
    protected void onCreate( Bundle savedInstanceState ) {

        super.onCreate( savedInstanceState );
        setContentView( R.layout.activity_main4 );
        initView();
        initViewAction();
    }

    private void initView() {

        mPreviewView = (PreviewView) findViewById( R.id.previewView );
        mImage = (ImageView) findViewById( R.id.image );
    }

    private void initViewAction() {

        Observable.interval( 1, TimeUnit.SECONDS )
            .observeOn( AndroidSchedulers.mainThread() )
            .subscribe( new Observer< Long >() {
                @Override
                public void onSubscribe( @NonNull Disposable d ) {

                }

                @Override
                public void onNext( @NonNull Long aLong ) {

                    Bitmap bitmap = mPreviewView.getBitmap();
                    if ( bitmap != null ) {
                        mImage.setImageBitmap( bitmap );
                    }
                }

                @Override
                public void onError( @NonNull Throwable e ) {

                }

                @Override
                public void onComplete() {

                }
            } );

        mXManager = new CameraXManager( this, this ) {
            @Override
            protected UseCase[] buildUseCases() {

                return new UseCase[]{
                    buildPreviewCase( mPreviewView ),
                    buildImageAnalysisCase( new Analyzer() {
                        @Override
                        @ExperimentalGetImage
                        public void analyze( @NonNull ImageProxy image ) {

                            Image image1 = image.getImage();
                            if ( image1 != null ) {
                                InputImage inputImage =
                                    InputImage.fromMediaImage( image1, image.getImageInfo().getRotationDegrees() );
                                mDetector.process( inputImage )
                                    .addOnSuccessListener( new OnSuccessListener< List< Face > >() {
                                        @Override
                                        public void onSuccess( List< Face > faces ) {

                                            for ( Face face : faces ) {
                                                Rect bounds = face.getBoundingBox();
                                                float rotY = face.getHeadEulerAngleY();  // Head is rotated to the right rotY degrees
                                                float rotZ = face.getHeadEulerAngleZ();  // Head is tilted sideways rotZ degrees

                                                // If landmark detection was enabled (mouth, ears, eyes, cheeks, and
                                                // nose available):
                                                FaceLandmark leftEar = face.getLandmark( FaceLandmark.LEFT_EAR );
                                                if ( leftEar != null ) {
                                                    PointF leftEarPos = leftEar.getPosition();
                                                }

                                                // If contour detection was enabled:
                                                List< PointF > leftEyeContour =
                                                    face.getContour( FaceContour.LEFT_EYE ).getPoints();
                                                List< PointF > upperLipBottomContour =
                                                    face.getContour( FaceContour.UPPER_LIP_BOTTOM ).getPoints();

                                                // If classification was enabled:
                                                if ( face.getSmilingProbability() != null ) {
                                                    float smileProb = face.getSmilingProbability();
                                                }
                                                if ( face.getRightEyeOpenProbability() != null ) {
                                                    float rightEyeOpenProb = face.getRightEyeOpenProbability();
                                                }

                                                // If face tracking was enabled:
                                                if ( face.getTrackingId() != null ) {
                                                    int id = face.getTrackingId();
                                                }
                                            }
                                        }
                                    } )
                                    .addOnFailureListener( new OnFailureListener() {
                                        @Override
                                        public void onFailure( @NonNull Exception e ) {

                                        }
                                    } )
                                    .addOnCompleteListener( new OnCompleteListener< List< Face > >() {
                                        @Override
                                        public void onComplete( @NonNull Task< List< Face > > task ) {

                                            image.close();
                                        }
                                    } );
                            }
                        }
                    } )
                };
            }

            @NonNull
            @Override
            protected CameraSelector provideCameraSelector() {

                CameraSelector defaultFrontCamera = CameraSelector.DEFAULT_FRONT_CAMERA;
                return defaultFrontCamera;
            }
        };

        // High-accuracy landmark detection and face classification
        FaceDetectorOptions highAccuracyOpts =
            new FaceDetectorOptions.Builder()
                .setPerformanceMode( FaceDetectorOptions.PERFORMANCE_MODE_ACCURATE )
                .setLandmarkMode( FaceDetectorOptions.LANDMARK_MODE_ALL )
                .setClassificationMode( FaceDetectorOptions.CLASSIFICATION_MODE_ALL )
                .build();
        mDetector = FaceDetection.getClient( highAccuracyOpts );
    }

    private void analysisBitmap( Bitmap bitmap ) {

    }
}